
export type AccountType = 'cash' | 'credit' | 'saving' | 'wealth'
export type AccountStatus = 'ok' | 'closed'
export type IoCateGroupType = 'in' | 'out'
export type IoLogType = 'in' | 'out' | 'txf' | 'adj'


export interface Account {
    id: number,
    name: string,
    type: AccountType,
    create_dt: string,
    balance: number,
    memo: string,
    status: AccountStatus,

    firstLogDate: string,   // 非数据库字段，记录该账户的第一条收支记录的日期
}

export interface IoCateGroup {
    id: number,
    label: string,
    type: IoCateGroupType,
    items: number[],
}

export interface IoCateItem {
    id: number,
    label: string,
}

export interface IoLog {
    id: number,
    account_id: number,
    happen_dt: string,
    type: IoLogType,
    io_cate: string, // 'in' | 'out' | 'txf' | 'adj' | '[?,?]'
    amount: number,
    memo: string,
    balance: number,
    pair_account_id: number,
    ts: number,
}

interface NativeLoadResult {
    accounts: Promise<string>           // Record<number, Account>
    accountOrders: Promise<string>      // number[]
    ioCateGroups: Promise<string>       // Record<number, IoCateGroup>
    ioCateGroupOrders: Promise<string>  // number[]
    ioCateItems: Promise<string>        // Record<number, IoCateItem>
}

export interface NativeJzbdb {
    dbPath: Promise<string>
    close(): Promise<void>
    load(): Promise<NativeLoadResult>

    account_new(data: string /* Partial<Account> */): Promise<string /* Account */>
    account_update(id: number, data: string /* Partial<Account> */): Promise<void>
    account_delete(id: number, type: AccountType): Promise<void>
    account_setOrder(type: AccountType, order: string /* number[] */): Promise<void>
    account_getBalance(id: number): Promise<number>
    
    ioCateGroup_new(data: string /* Partial<IoCateGroup> */): Promise<string /* IoCateGroup */>
    ioCateGroup_update(id: number, data: string /* Partial<IoCateGroup> */): Promise<void>
    ioCateGroup_delete(type: IoCateGroupType, id: number): Promise<void>
    ioCateGroup_setOrder(type: IoCateGroupType, order: string /* number[] */): Promise<void>

    ioCateItem_new(groupId: number, data: string /* Partial<IoCateItem> */): Promise<string /* IoCateItem */>
    ioCateItem_update(id: number, data: string /* Partial<IoCateItem> */): Promise<void>
    ioCateItem_delete(groupId: number, itemId: number): Promise<void>
    ioCateItem_setOrder(groupId: number, order: string /* number[] */): Promise<void>

    ioLog_firstDate(accountId: number): Promise<string>
    ioLog_load(accountId: number, toYear?: string): Promise<string /* IoLog[] */>
    ioLog_findPair(pairAccountId: number, happenDt: string, ts: number): Promise<string /* IoLog */>
    ioLog_new(log: string /* IoLog */): Promise<string /* IoLog[] */>
    ioLog_delete(id: number): Promise<string /* IoLog[] */>
    ioLog_update(data: string /* Partial<IoLog> */): Promise<string /* IoLog[] */>
    ioLog_query(data: string /* {fromDt: string, toDt: string, memo: string} */): Promise<string /* IoLog[] */>

    snapshot(memo: string): Promise<void>
}

export class Jzbdb {
    
    private static _instance = new Jzbdb()

    public static getInstance(): Jzbdb {
        return this._instance
    }

    private _ndb: NativeJzbdb | null = null

    public dbPath: string = ''
}